<script setup lang="tsx">
import { Form, FormSchema } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { ref, PropType, reactive, watch, computed } from 'vue'
import { TableData } from '@/api/table/types'
import { useValidator } from '@/hooks/web/useValidator'
import { useI18n } from '@/hooks/web/useI18n'
import { useUserStoreWithOut } from '@/store/modules/user'
import { ElMessageBox, ElMessage, ElIcon, ElImage, ElButton } from 'element-plus'
import type { UploadRawFile } from 'element-plus'
import type { UploadFile, UploadFiles } from 'element-plus'
import { Dialog } from '@/components/Dialog'
import { useClipboard } from '@/hooks/web/useClipboard'

const userStore = useUserStoreWithOut()

const { t } = useI18n()

const { required } = useValidator()

const props = defineProps({
  currentRow: {
    type: Object as PropType<Nullable<TableData>>,
    default: () => null
  },
  formSchema: {
    type: Array as PropType<FormSchema[]>,
    default: () => []
  }
})

const PATH_URL = import.meta.env.VITE_API_BASE_PATH
const dialogVisible = ref(false)
const dialogImageUrl = ref('')
const uploadFilesStorage = ref<UploadFiles>([])
const coverUrl = ref('')
const coverFileList = ref<UploadFiles>([])

// 提取所有图片链接
const imageUrls = computed(() => {
  return uploadFilesStorage.value
    .map((file: UploadFile) => {
      // 优先使用 response 中的 URL（服务器返回的）
      const response = file.response as any

      // 如果 response.data 直接是字符串（URL）
      if (typeof response?.data === 'string' && response.data) {
        return response.data
      }

      // 尝试多种可能的响应格式
      if (response?.data?.data?.url) {
        return response.data.data.url
      }
      if (response?.data?.url) {
        return response.data.url
      }
      if (response?.url) {
        return response.url
      }
      if (response?.data?.src) {
        return response.data.src
      }
      if (response?.src) {
        return response.src
      }

      // 其次使用 file.url（排除 blob: 开头的本地预览 URL）
      if (file.url && !file.url.startsWith('blob:')) {
        return file.url
      }

      // 如果文件已上传成功（status === 'success'），但 URL 在 response 中，尝试从 name 或 raw 中获取
      if (file.status === 'success' && file.response) {
        // Element Plus Upload 组件上传成功后，URL 应该已经设置到 file.url
        // 但如果还是 blob:，可能需要等待响应处理
        return null
      }

      return null
    })
    .filter((url): url is string => url !== null && url !== '' && !url.startsWith('blob:'))
})

// 复制功能
const { copy, copied, text } = useClipboard()

const copyImageUrl = (url: string) => {
  copy(url)
  ElMessage.success('链接已复制到剪贴板')
}

const schema = reactive<FormSchema[]>([
  {
    field: 'title',
    label: t('tableDemo.title'),
    component: 'Input',
    formItemProps: {
      rules: [required()]
    }
  },
  {
    field: 'author',
    label: t('tableDemo.author'),
    component: 'Input',
    formItemProps: {
      rules: [required()]
    }
  },
  {
    field: 'tag',
    label: '标签',
    component: 'InputTag',
    formItemProps: {
      rules: [required()]
    }
  },
  {
    field: 'status',
    label: '状态',
    component: 'Select',
    componentProps: {
      style: {
        width: '100%'
      },
      options: [
        {
          label: '草稿',
          value: 0
        },
        {
          label: '上架',
          value: 1
        }
      ]
    }
  },
  {
    field: 'coverUrl',
    component: 'Upload',
    label: '封面',
    formItemProps: {
      // rules: [required()]
    },
    componentProps: {
      action: PATH_URL + '/system/oss/upload',
      headers: {
        [userStore.getTokenKey ?? 'Authorization']: userStore.getToken ?? ''
      },
      listType: 'picture-card',
      showFileList: false,
      onSuccess: (response: any, uploadFile: UploadFile) => {
        const url =
          (typeof response?.data === 'string' ? response.data : null) ||
          response?.data?.data?.url ||
          response?.data?.url ||
          response?.url ||
          response?.data?.src ||
          response?.src
        if (url && uploadFile) {
          uploadFile.url = url
          // 同步更新 coverUrl
          coverUrl.value = url
        }
      },
      onChange: (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
        // 同步更新 coverFileList 以便在 slots 中使用
        coverFileList.value = uploadFiles
        // 从文件列表中提取 URL 并更新 coverUrl
        if (uploadFiles.length === 0) {
          coverUrl.value = ''
        } else {
          // 获取最后一个文件的 URL
          const lastFile = uploadFiles[uploadFiles.length - 1]
          if (lastFile.status === 'success' && lastFile.url && !lastFile.url.startsWith('blob:')) {
            coverUrl.value = lastFile.url
          }
        }
      },
      beforeUpload: (rawFile: UploadRawFile) => {
        if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png') {
          ElMessage.error('请上传jpg或者png格式的图片!')
          return false
        } else if (rawFile.size / 1024 / 1024 > 2) {
          ElMessage.error('图片大小不能超过 2MB!')
          return false
        }
        return true
      },
      slots: {
        default: () => (
          <>
            {coverUrl.value ? <ElImage src={coverUrl.value} style="height: 148px" /> : null}
            {!coverUrl.value ? (
              <ElIcon class="avatar-uploader-icon" size="large">
                add
              </ElIcon>
            ) : null}
          </>
        )
      }
    },
    colProps: {
      span: 24
    }
  },
  {
    field: 'images',
    component: 'Upload',
    label: '内容所需图片',
    componentProps: {
      limit: 10,
      action: PATH_URL + '/system/oss/upload',
      headers: {
        [userStore.getTokenKey ?? 'Authorization']: userStore.getToken ?? ''
      },
      data: {},
      fileList: [],
      multiple: true,
      listType: 'picture-card',
      onPreview: (uploadFile: UploadFile) => {
        dialogImageUrl.value = uploadFile.url!
        dialogVisible.value = true
      },
      onRemove: (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
        uploadFilesStorage.value = uploadFiles
      },
      beforeRemove: (uploadFile: UploadFile) => {
        return ElMessageBox.confirm(`确定删除 ${uploadFile.name} ?`).then(
          () => true,
          () => false
        )
      },
      onExceed: (files: File[]) => {
        ElMessage.warning(`限制上传10张证件，你选择了 ${files.length} 个文件`)
      },
      onChange: (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
        // 当文件上传成功后，确保 URL 被正确设置
        if (uploadFile.status === 'success' && uploadFile.response) {
          const response = uploadFile.response as any
          // 如果 file.url 还是 blob: 或不存在，尝试从 response 中提取 URL
          if (!uploadFile.url || uploadFile.url.startsWith('blob:')) {
            // 优先检查 response.data 是否是直接字符串
            const url =
              (typeof response?.data === 'string' ? response.data : null) ||
              response?.data?.data?.url ||
              response?.data?.url ||
              response?.url ||
              response?.data?.src ||
              response?.src
            if (url) {
              uploadFile.url = url
            }
          }
        }
        uploadFilesStorage.value = uploadFiles
      },
      onSuccess: (response: any, uploadFile: UploadFile) => {
        // 上传成功回调，确保 URL 被设置到 file.url
        // 优先检查 response.data 是否是直接字符串
        const url =
          (typeof response?.data === 'string' ? response.data : null) ||
          response?.data?.data?.url ||
          response?.data?.url ||
          response?.url ||
          response?.data?.src ||
          response?.src
        if (url && uploadFile) {
          uploadFile.url = url
        }
      },
      slots: {
        default: () => (
          <>
            <ElIcon class="avatar-uploader-icon" size="large">
              add
            </ElIcon>
          </>
        ),
        tip: () => (
          <>
            <div class="el-upload__tip">提示：在此上传的图片是编辑内容时需要插入的</div>
            {imageUrls.value.length > 0 && (
              <div
                class="image-urls-container"
                style="margin-top: 16px; padding: 16px; background-color: #f5f7fa; border-radius: 4px;"
              >
                <div style="margin-bottom: 12px; font-weight: 600; color: #303133;">
                  已上传图片链接：
                </div>
                {imageUrls.value.map((url: string, index: number) => (
                  <div
                    key={index}
                    class="image-url-item"
                    style="display: flex; align-items: center; margin-bottom: 8px; padding: 8px; background-color: #fff; border-radius: 4px;"
                  >
                    <span
                      style="flex: 1; color: #606266; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;"
                      title={url}
                    >
                      {url}
                    </span>
                    <ElButton
                      type="primary"
                      size="small"
                      style="margin-left: 12px; flex-shrink: 0;"
                      onClick={() => copyImageUrl(url)}
                    >
                      {copied.value && text.value === url ? '已复制' : '复制'}
                    </ElButton>
                  </div>
                ))}
              </div>
            )}
          </>
        )
      }
    },
    colProps: {
      span: 24
    }
  },
  {
    field: 'content',
    label: t('exampleDemo.content'),
    component: 'Editor',
    componentProps: {
      toolbarConfig: {
        // 排除所有视频相关的按钮
        excludeKeys: ['insertVideo', 'uploadVideo', 'video']
      },
      editorConfig: {
        MENU_CONF: {
          // 禁用所有视频相关功能
          insertVideo: {
            disabled: true
          },
          uploadVideo: {
            disabled: true
          },
          video: {
            disabled: true
          },
          // 配置插入图片功能（支持插入网络图片）
          insertImage: {
            // 是否显示链接地址输入框（插入网络图片时）
            showLinkImgAlt: true,
            // 是否显示图片的链接地址输入框（可以设置点击图片跳转的链接）
            showLinkImgHref: true,
            // 检查图片链接
            checkImage(src: string, _alt?: string, _href?: string): boolean | string | undefined {
              // 可以在这里验证图片链接是否有效
              if (!src) {
                return '图片地址不能为空'
              }
              // 验证是否是有效的图片链接
              if (
                !src.startsWith('http://') &&
                !src.startsWith('https://') &&
                !src.startsWith('data:')
              ) {
                return '请输入有效的图片地址'
              }
              return true
            }
          },
          // 配置上传图片功能（如果需要）
          uploadImage: {
            // 服务器上传地址，如果需要上传功能
            // server: PATH_URL + '/system/oss/upload',
            // 字段名
            fieldName: 'file',
            // 最大上传大小（单位：KB）
            maxFileSize: 10 * 1024, // 10MB
            // 允许的文件类型
            allowedFileTypes: ['image/*'],
            // 上传时的请求头
            headers: {
              [userStore.getTokenKey ?? 'Authorization']: userStore.getToken ?? ''
            },
            // 上传成功后的处理
            onSuccess(_file: File, res: any) {
              // 上传成功后的处理逻辑
              return res.data?.url || res.url || ''
            }
          }
        }
      }
    },
    colProps: {
      span: 24
    }
  }
])

const { formRegister, formMethods } = useForm()
const { setValues, getFormData, getElFormExpose } = formMethods

const submit = async () => {
  const elForm = await getElFormExpose()
  const valid = await elForm?.validate().catch((err) => {
    console.log(err)
  })
  if (valid) {
    const formData = await getFormData()
    if (formData) {
      formData.tag = formData.tag.join(',')
      formData.coverUrl = coverUrl.value
      delete formData.images
    }
    return formData
  }
}

watch(
  () => props.currentRow,
  (currentRow) => {
    if (!currentRow) {
      // 重置表单时，清空 coverUrl 相关数据
      coverUrl.value = ''
      coverFileList.value = []
      setValues({ coverUrl: [] })
      return
    }
    const row = JSON.parse(JSON.stringify(currentRow))
    if (row.tag) {
      row.tag = row.tag.split(',')
    } else {
      row.tag = []
    }
    // 处理 coverUrl：将字符串 URL 转换为 Upload 组件需要的数组格式
    if (row.coverUrl) {
      coverUrl.value = row.coverUrl
      coverFileList.value = [
        {
          name: 'cover.jpg',
          url: row.coverUrl,
          status: 'success'
        } as UploadFile
      ]
      row.coverUrl = coverFileList.value
    } else {
      coverUrl.value = ''
      coverFileList.value = []
      row.coverUrl = []
    }
    setValues(row)
  },
  {
    deep: true,
    immediate: true
  }
)

defineExpose({
  submit
})
</script>

<template>
  <Form @register="formRegister" :schema="schema" />
  <Dialog v-model="dialogVisible" title="图片预览" :max-height="800">
    <img style="width: 100%" :src="dialogImageUrl" alt="Preview Image" />
  </Dialog>
</template>

<style lang="less">
.el-icon.avatar-uploader-icon {
  width: 148px;
  height: 148px;
  font-size: 28px;
  color: #8c939d;
  text-align: center;
}
</style>
